package service

import (
	"encoding/json"
	"errors"
	"fmt"
	"go.uber.org/zap"
	"niu-video/app/consts"
	"niu-video/app/model"
	"niu-video/app/repository"
	"niu-video/pkg/logger"
	"niu-video/pkg/rabbitmq"
	"niu-video/pkg/redis"
	"strconv"
)

var CollectService = newCollectService()

func newCollectService() *collectService {
	return &collectService{}
}

type collectService struct {
}

func (l *collectService) Collect(request model.CollectAction, userId int64) string {
	// 查询有没有这个视频
	video := repository.VideoRepository.GetOne(request.VideoID)
	if video.VideoID == 0 {
		return "该视频不存在！"
	}
	switch request.ActionType {
	case 1:
		// 收藏
		l.collect(request.VideoID, userId)
		UserService.UserAction(model.UserAction{
			VideoId: request.VideoID,
			Ratio:   10,
		}, userId)
		return "收藏成功！"
	case 2:
		l.unCollect(request.VideoID, userId)
		UserService.UserAction(model.UserAction{
			VideoId: request.VideoID,
			Ratio:   -10,
		}, userId)
		return "您已取消收藏"
	}
	return ""
}

func (l *collectService) collect(videoId int64, userId int64) {
	res := redis.Redis.Eval(consts.LuaScript, []string{
		fmt.Sprintf("%s:%d:%d", consts.REDIS_COLLECT_PREFIX, videoId, userId),
		fmt.Sprintf("%s:%d", consts.REDIS_COLEECT_COUNTER_PREFIX, videoId)})
	if !res {
		redis.Redis.Decrement(fmt.Sprintf("%s:%d", consts.REDIS_COLEECT_COUNTER_PREFIX, videoId))
	}
	collect := model.CollectMessage{
		VideoID:    videoId,
		UserID:     userId,
		ActionType: 1,
	}
	collectMessage, err := json.Marshal(collect)
	logger.LogIf(err)
	rabbit := rabbitmq.NewRabbitMQ(consts.RABBITMQ_COLLECT_EXCHANGE, consts.RABBITMQ_COLLECT_ROUTE, consts.RABBITMQ_COLLECT_QUEUE)
	defer rabbit.Close()
	rabbit.SendMessage(rabbitmq.Message{Body: string(collectMessage)})
}

func (l *collectService) IsCollect(videoId int64, userId int64) bool {
	is := redis.Redis.Has(fmt.Sprintf("%s:%d:%d", consts.REDIS_COLLECT_PREFIX, videoId, userId))
	if is {
		return is
	}
	collect := repository.CollectRepository.GetUserCollect(videoId, userId)
	if collect.UserCollectID != 0 {
		return true
	}
	return false
}
func (c *collectService) unCollect(videoId int64, userId int64) {
	redis.Redis.Eval(consts.UnLuaScript, []string{
		fmt.Sprintf("%s:%d:%d", consts.REDIS_COLLECT_PREFIX, videoId, userId),
		fmt.Sprintf("%s:%d", consts.REDIS_COLEECT_COUNTER_PREFIX, videoId)})
	collect := model.CollectMessage{
		VideoID:    videoId,
		UserID:     userId,
		ActionType: 2,
	}
	collectMessage, err := json.Marshal(collect)
	logger.LogIf(err)
	rabbit := rabbitmq.NewRabbitMQ(consts.RABBITMQ_COLLECT_EXCHANGE, consts.RABBITMQ_COLLECT_ROUTE, consts.RABBITMQ_COLLECT_QUEUE)
	defer rabbit.Close()
	rabbit.SendMessage(rabbitmq.Message{Body: string(collectMessage)})
}

func (c *collectService) CollectCount(videoId int64) int64 {
	cntStr := redis.Redis.Get(fmt.Sprintf("%s:%d", consts.REDIS_COLEECT_COUNTER_PREFIX, videoId))
	if cntStr == "" {
		return 0
	}
	cnt, err := strconv.ParseInt(cntStr, 10, 64)
	if err != nil {
		logger.ErrorString("collect", "CollectCount", err.Error())
		return 0
	}
	return cnt
}

func (c *collectService) List(request model.PageRequest, userId int64) (interface{}, error) {
	list := repository.CollectRepository.GetUserCollectByPage(request.Page, request.PageSize, userId)
	videos, err := VideoService.concurrencyGetVideos(list, userId)
	if err != nil {
		logger.Error("video", zap.String("list", "视频列表查询失败"))
		return videos, errors.New("视频列表查询失败")
	}
	return videos, nil
}
